package net.wicp.tams.duckula.common;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import org.apache.commons.collections.CollectionUtils;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.zookeeper.data.Stat;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import lombok.extern.slf4j.Slf4j;
import net.wicp.tams.commons.Result;
import net.wicp.tams.duckula.common.beans.ColHis;
import net.wicp.tams.duckula.common.beans.Count;
import net.wicp.tams.duckula.common.beans.Pos;
import net.wicp.tams.duckula.common.beans.Task;
import net.wicp.tams.duckula.common.constant.ZkPath;

@Slf4j
public abstract class ZkUtil {

	public static Stat exists(ZkPath path) {
		return ZkClient.getInst().exists(path.getRoot());
	}

	public static Stat exists(ZkPath path, String taskId) {
		return ZkClient.getInst().exists(path.getPath(taskId));
	}

	public static Result del(ZkPath path, String subNode) {
		Stat stat = exists(path, subNode);
		if (stat != null) {
			Result retStat = ZkClient.getInst().deleteNode(path.getPath(subNode));
			return retStat;
		}
		return Result.getSuc("无需删除");
	}

	public static List<String> findSubNodes(ZkPath path) {
		List<String> retlist = ZkClient.getInst().getChildren(path.getRoot());
		return retlist;
	}

	public static Task buidlTask(String taskId) {
		Task retobj = JSONObject.toJavaObject(ZkClient.getInst().getZkData(ZkPath.tasks.getPath(taskId)), Task.class);
		return retobj;
	}

	public static InterProcessMutex lockTaskPath(String taskId) {
		return ZkClient.getInst().lockPath(ZkPath.tasks.getPath(taskId));
	}

	public static List<String> lockIps(String taskId) {
		List<String> nodes = ZkClient.getInst().getChildren(ZkPath.tasks.getPath(taskId));
		List<String> retlist = new ArrayList<>();
		for (String node : nodes) {
			String zkValue = ZkClient.getInst()
					.getZkDataStr(String.format("%s/%s", ZkPath.tasks.getPath(taskId), node));
			retlist.add(zkValue);
		}
		return retlist;
	}

	public static Pos buidlPos(String taskId) {
		Pos retobj = JSONObject.toJavaObject(ZkClient.getInst().getZkData(ZkPath.pos.getPath(taskId)), Pos.class);
		return retobj;
	}

	public static Map<String, SortedSet<ColHis>> buildCols(String dbInstName) {
		Map<String, SortedSet<ColHis>> ret = new HashMap<>();
		try {
			String dbInstRootPath = ZkPath.cols.getPath(dbInstName);
			Stat stat = ZkUtil.exists(ZkPath.cols, dbInstName);
			if (stat == null) {
				ZkClient.getInst().createNode(dbInstRootPath, null);
			}
			List<String> colsTables = ZkClient.getInst().getChildren(dbInstRootPath);
			if (CollectionUtils.isEmpty(colsTables)) {
				return ret;
			}
			for (String colsTable : colsTables) {
				String path = String.format("%s/%s", dbInstRootPath, colsTable);
				List<ColHis> list = JSONObject.parseArray(ZkClient.getInst().getZkDataStr(path), ColHis.class);
				SortedSet<ColHis> templist = new TreeSet<>();
				templist.addAll(list);
				ret.put(colsTable, templist);
			}
		} catch (Exception e) {
			log.error("组装cols出错", e);
		}
		return ret;
	}

	public static void updateCols(String dbInstName, String colsTable, SortedSet<ColHis> list) {
		String keyPath = String.format("%s/%s/%s", ZkPath.cols.getRoot(), dbInstName, colsTable);
		ZkClient.getInst().createOrUpdateNode(keyPath, JSONArray.toJSONString(list));
	}

	public static void updatePos(String taskId, Pos pos) {
		ZkClient.getInst().createOrUpdateNode(ZkPath.pos.getPath(taskId), JSONObject.toJSONString(pos));
	}

	public static void updateCount(String taskId, Count count) {
		ZkClient.getInst().createOrUpdateNode(ZkPath.counts.getPath(taskId), JSONObject.toJSONString(count));
	}

	public static void updateCos(String taskId, ColHis colhis) {
		try {
			String jsonstr = ZkClient.getInst().getZkDataStr(ZkPath.cols.getColsPath(taskId, colhis));
			List<ColHis> list = JSONObject.parseArray(jsonstr, ColHis.class);
			boolean isInclude = false;
			for (ColHis colHis2 : list) {
				if (colHis2.getTime() == colhis.getTime()) {
					isInclude = true;
					break;
				}
			}
			if (!isInclude) {
				list.add(colhis);
				Collections.sort(list);
				ZkClient.getInst().createOrUpdateNode(ZkPath.cols.getColsPath(taskId, colhis),
						JSONObject.toJSONString(list));
			}
		} catch (Exception e) {
			log.error("更新列失败", e);
			throw new IllegalStateException();
		}

	}
}
